package com.uuah.server.transport;

import java.util.Iterator;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.uuah.exception.UuahRuntimeException;
import com.uuah.server.api.IThreadSafeAccess;
import com.uuah.server.api.transport.IMessageAdapter;
import com.uuah.server.config.i18n.ServerMessages;

/**
 *
 * TODO comment ...
 *
 * <p>
 * update record:updator，update time，update content and version
 * </p>
 *
 * @author <a href="jonny_quan@hotmail.com">jonny</a>
 * @date 2009 2009-3-27 下午03:14:13
 * @version 1.0.0
 */
public final class MessageAdapter extends AbstractMessageAdapter implements
		IMessageAdapter {
	private transient Logger logger = LoggerFactory
			.getLogger(MessageAdapter.class);
	private static final long serialVersionUID = 1908152148142575505L;

	protected Object message;

	protected MessageAdapter() {
		super();
	}

	public MessageAdapter(Object message) {
		if (message == null) {
			this.message = NullPayload.getInstance();
		} else {
			this.message = message;
		}
	}

	public MessageAdapter(Object message, IMessageAdapter previous) {
		super(previous);
		if (previous != null) {
			if (message == null) {
				this.message = NullPayload.getInstance();
			} else {
				this.message = message;
			}

			for (Iterator iterator = previous.getPropertyNames().iterator(); iterator
					.hasNext();) {
				String name = (String) iterator.next();
				try {
					Object value = previous.getProperty(name);
					if (null == value) {
						logger.warn("Detected concurrent access to property "
								+ name + " for " + previous);
					} else {
						setProperty(name, value);
					}
				} catch (Exception e) {
					throw new UuahRuntimeException(ServerMessages
							.failedToReadPayload(), e);
				}
			}
		} else {
			throw new IllegalArgumentException(
					"previousAdapter may not be null");
		}
	}

	public MessageAdapter(Object message, Map properties) {
		this(message);
		if (properties != null) {
			this.properties.addRequestProperties(properties);
		}
	}

	public Object getPayload() {
		return message;
	}

	public void setPayload(Object payload) {
		synchronized (message) {
			message = payload;
		}
	}

	public String getUniqueId() {
		return id;
	}

	public IThreadSafeAccess newThreadCopy() {
		return new MessageAdapter(getPayload(), this);
	}

}
